{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true,
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "手动实现感知机学习算法的原始形式，其中将参数 w 和 b 合并为一个参数向量，方便实现：\n",
    "$\\vec{w}=<w^{(1)},w^{(2)},...,w^{(n)},b>$，\n",
    "$\\vec{x_i}=<x_i^{(1)}, x_i^{(2)},...,x_i^{(n)}>$，那么$w\\cdot x+b$\n",
    "就可简写为：$w\\cdot x$，实现时更方便。\n",
    "\n",
    "准备鸢尾花数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "outputs": [],
   "source": [
    "from sklearn import datasets\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "from matplotlib import pyplot as plt\n",
    "from matplotlib.colors import ListedColormap"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(150, 4) (150,)\n",
      "[0 0 0 0 0] [1 1 1 1 1] [2 2 2 2 2]\n",
      "Class labels: [-1  1]\n",
      "(100, 2) (100,)\n"
     ]
    }
   ],
   "source": [
    "iris = datasets.load_iris()\n",
    "print(iris['data'].shape, iris['target'].shape) # (150, 4) (150,) 一共有4个特征\n",
    "print(iris['target'][:5], iris['target'][50:55], iris['target'][100:105])\n",
    "\n",
    "X = iris.data[:100,[0,2]] # 只使用2个特征:sepal length 和 petal length 以及2个类别\n",
    "y = iris.target[:100]\n",
    "y = np.where(y==1, 1, -1) # 1表示setosa杂色鸢尾，-1表示负例\n",
    "print('Class labels:', np.unique(y))\n",
    "print(X.shape, y.shape)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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RSp3p6enp+h7n/3sZ5k+fXrwGLq7u4N/h9RO6AJd33+OJf55JpaW37kkksQc8ryEPnaZSvAhilQ33XQTt956a8F3LOQf/uEfuOWWWzjllFMYN24cnZ2dAGzevJkxY8Zw2WWX0d7ezq9//Wtmz55Ne3s7Y8eOZXHuMmD27NksW7YMgGeeeYYpU6Ywfvx4Tj31VPbs2cO+ffuYM2cOY8eOZcKECTzxxBOHxLV7924uvPBCxo0bx2mnncbatWsPxHfppZdyxhlncOmll1a+41JXoQt006bBxIkHk3pPTzQ/bVp12222wjAkiznkeanHsctMgi8shtTyOZWzZs3iwQcfPDD/4IMPMmLECJ5//nmWL1/O6tWrWblyJT/9aTQCw/PPP88111zDhg0b2LlzJ9u2bWP9+vWsW7eOOXPm9Nr222+/zaxZs1iyZAlr1qzhscce4/DDD+fWW2/FzFi3bh333Xcfl19++SGDj3V2djJhwgTWrl3L5z//eS677LID723cuJHHHnuM++67r7KdlrorVaCbP7/6Al1PD3R1werVB5P8xInRfFdX5VfyoX7nQkoac6jzUrdjV6qLayOmaocqKOwanJ9q0UX4/e9/v2/bts1Xr17tU6ZM8QULFvioUaN8/PjxPn78eD/hhBP8rrvu8pdeesnb2toOfG737t3+vve9z6+99lp/9NFHff/+/e7ufvnll/u3v/1tX7t2rU+ZMuWQ77vwwgv98ccfPzB/5pln+po1a/yJJ57w888/393dOzo6/Fe/+tWBdUaOHOldXV3e2dnpCxcuLLkvGqog3fr+W61V9/b9+907Onr/bnR0RMurEep3LqRKYg5xXmp17CgzVEFmruAhXJFq5syZLFu2jAceeIBZs2bh7tx8880Hhgx+4YUXuOKKKwB417vedeBzRx99NGvWrGHatGnccccdXHnlldUFElNhDNJcQhXoBgyAPjeosWJF7x6XlQhdGE7aVh5n3UpiDnFe6lFUz1SCD1UMmTVrFvfffz/Lli1j5syZnHPOOdx99928/vrrAGzbto3t27cf8rmdO3fS09PDRRddxOc+9zlWrVrV6/0xY8bw6quv8swzzwCwZ88euru7+eAHP8jS3KMGn3vuOV5++WXGjBnT67OF6zz55JMMHz6cI444orodlczq7IRjj+297Nhjo+XVCFmATNJGXUm7eoiY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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X[:50, 0], X[:50, 1], color='red', marker='o', label='setosa')\n",
    "plt.scatter(X[50:100, 0], X[50:100, 1], color='blue', marker='x', label='versicolor')\n",
    "plt.xlabel('sepal length [cm]')\n",
    "plt.ylabel('petal length [cm]')\n",
    "plt.legend(loc='upper left')\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "outputs": [],
   "source": [
    "class Perceptron(object):\n",
    "     \"\"\"Perceptron classifier.\n",
    "\n",
    "     Parameters\n",
    "     ------------\n",
    "     eta : float 学习率 (between 0.0 and 1.0)\n",
    "     n_iter : int 迭代次数. 整个训练迭代完一次叫一次iter（或epoch）\n",
    "     random_state : int 用于初始化参数的随机数种子\n",
    "\n",
    "     Attributes\n",
    "     -----------\n",
    "     w_ : 1d-array 模型权重参数 需要通过训练求得\n",
    "     errors_ : list 每次迭代中，误分类点个数\n",
    "     \"\"\"\n",
    "     def __init__(self, eta=0.01, n_iter=50, random_state=1):\n",
    "         self.eta = eta\n",
    "         self.n_iter = n_iter\n",
    "         self.random_state = random_state\n",
    "\n",
    "     def fit(self, X, y):\n",
    "         \"\"\"Fit training data.\n",
    "\n",
    "         Parameters\n",
    "        ----------\n",
    "         X : {array-like}, shape = [n_samples, n_features] 训练集样本shape [样本数，样本特征数]\n",
    "         y : array-like, shape = [n_samples], 真实类别标记\n",
    "\n",
    "         Returns\n",
    "         -------\n",
    "         self : object\n",
    "         \"\"\"\n",
    "         rgen = np.random.RandomState(self.random_state) # 用于初始化w\n",
    "         # # 使用正态分布初始化w, 注意w 是考虑了bias的增广向量<w,b>\n",
    "         self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])\n",
    "         self.errors_ = []\n",
    "         for _ in range(self.n_iter):\n",
    "             errors = 0\n",
    "             for xi, target in zip(X, y):\n",
    "                 # uodate用于计算 \\eta*yi\n",
    "                 # 注意，当x_i被正确分类时，target - self.predict(xi)=0，即update=0，不更新\n",
    "                 # 当target - self.predict(xi)不等于0时，update = +2*\\eta 或者 -2*\\eta\n",
    "                 # 这样实现是为了代码更简洁。当然也可以直接先判断target * self.predict(xi)的符号\n",
    "                 # 只有异号时才进行update的计算：update = \\eta* target即+1*\\eta 或者-1*\\eta\n",
    "                 update = self.eta * (target - self.predict(xi))\n",
    "                 self.w_[1:] += update * xi # 更新w\n",
    "                 self.w_[0] += update # 更新b\n",
    "                 errors += int(update != 0.0)\n",
    "             self.errors_.append(errors)\n",
    "         return self\n",
    "\n",
    "     def net_input(self, X):\n",
    "         \"\"\"Calculate net input\"\"\"\n",
    "         return np.dot(X, self.w_[1:]) + self.w_[0]\n",
    "\n",
    "     def predict(self, X):\n",
    "         \"\"\"Return class label after unit step\"\"\"\n",
    "         return np.where(self.net_input(X) >= 0.0, 1, -1)"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# 训练\n",
    "ppn = Perceptron(eta=0.1, n_iter=10)\n",
    "ppn.fit(X, y)\n",
    "plt.plot(range(1, len(ppn.errors_) + 1), ppn.errors_, marker='o')\n",
    "plt.xlabel('Epochs')\n",
    "plt.ylabel('Number of updates')\n",
    "plt.xlim(0)\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "outputs": [],
   "source": [
    "# 绘制分类决策边界：\n",
    "def plot_decision_regions(X, y, classifier, test_idx=None, resolution=0.02):\n",
    "     # setup marker generator and color map\n",
    "     markers = ('s', 'x', 'o', '^', 'v')\n",
    "     colors = ('red', 'blue', 'lightgreen', 'gray', 'cyan')\n",
    "     cmap = ListedColormap(colors[:len(np.unique(y))])\n",
    "\n",
    "     # plot the decision surface\n",
    "     x1_min, x1_max = X[:, 0].min() - 1, X[:, 0].max() + 1\n",
    "     x2_min, x2_max = X[:, 1].min() - 1, X[:, 1].max() + 1\n",
    "     xx1, xx2 = np.meshgrid(np.arange(x1_min, x1_max, resolution),\n",
    "                            np.arange(x2_min, x2_max, resolution))\n",
    "     Z = classifier.predict(np.array([xx1.ravel(), xx2.ravel()]).T)\n",
    "     Z = Z.reshape(xx1.shape)\n",
    "     plt.contourf(xx1, xx2, Z, alpha=0.3, cmap=cmap)\n",
    "     plt.xlim(xx1.min(), xx1.max())\n",
    "     plt.ylim(xx2.min(), xx2.max())\n",
    "\n",
    "     for idx, cl in enumerate(np.unique(y)):\n",
    "         plt.scatter(x=X[y == cl, 0], y=X[y == cl, 1],\n",
    "         alpha=0.8, c=colors[idx],\n",
    "         marker=markers[idx], label=cl,\n",
    "         edgecolor='black')\n",
    "\n",
    "     # highlight test samples\n",
    "     if test_idx:\n",
    "         # plot all samples\n",
    "         X_test, y_test = X[test_idx, :], y[test_idx]\n",
    "         plt.scatter(X_test[:, 0], X_test[:, 1],\n",
    "                     c='', edgecolor='black', alpha=1.0,\n",
    "                     linewidth=1, marker='o',\n",
    "                     s=100, label='test set')"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "outputs": [
    {
     "data": {
      "text/plain": "<Figure size 432x288 with 1 Axes>",
      "image/png": "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\n"
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_decision_regions(X, y, classifier=ppn)\n",
    "plt.xlabel('sepal length [cm]')\n",
    "plt.ylabel('petal length [cm]')\n",
    "plt.legend(loc='upper left')\n",
    "plt.show()"
   ],
   "metadata": {
    "collapsed": false,
    "pycharm": {
     "name": "#%%\n"
    }
   }
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}